using System;
using System.Data;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Collections;
using System.Configuration;

namespace NetFramework.DataAccess
{
	/// <summary>
	/// DataSourceFactory returns DataSource objects.
	/// Maintains/refreshes internal cache of DataSources.
	/// Config info retrieved from Framework.DataAccess.dll.config
	/// </summary>
	internal class DataSourceFactory
	{
		private const string DEFAULT_DATASOURCE_NAME = "DEFAULT_DATASOURCE_NAME";

		private static Hashtable _dataSources = null;
		private static IDataSource _defaultDataSource = null;

		static DataSourceFactory()
		{
			LoadCache();
		}

		private static void LoadCache()
		{
			try
			{
				dataAccessSettings settings = 
					(dataAccessSettings)ConfigurationSettings.GetConfig("dataAccessSettings");

				_dataSources = new Hashtable();
				foreach(dataSource ds in settings.dataSources)
				{
					DataProvider provider = 
						DataProviderFactory.GetDataProvider(ds.provider);

					DataSource dataSource = 
						new DataSource(ds.name, provider, ds.connectionString, 
						ds.dataOperationsPath, provider.ParameterNamePrefix,
						ds.commandTimeout);
					_dataSources.Add(dataSource.Name, dataSource);

					if(ds.isDefault) 
					{
						_defaultDataSource = dataSource;
					}
				}
			}
			catch(Exception e)
			{
				throw new DataAccessException("Error loading cache from config.", e);
			}
		}

		//only static methods
		private DataSourceFactory() {}

		public static IDataSource GetDataSource()
		{
			return GetDataSource(DEFAULT_DATASOURCE_NAME);
		}

		public static IDataSource GetDataSource(string dataSourceName)
		{
			IDataSource ds = null;

			if(dataSourceName.Equals(DEFAULT_DATASOURCE_NAME)) 
				ds = _defaultDataSource;
			else
				ds = _dataSources[dataSourceName] as DataSource;

			if(ds == null) 
			{
				//TODO: specialize the exception, perhaps DataSourceNotFoundException
				throw new DataAccessException("DataSource with name '" + dataSourceName + "' not found.");
			}

			return ds;
		}

	}
}
